﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Media.Effects;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Collections;
using System.Reflection;
using System.Windows.Ink;
using System.Windows.Media.Animation;

namespace TouchUmlUI
{
    public class KlasaObj : AssociableObj 
    {        

        public enum OBJ { INTERFACE, CLASS };

        public struct AttributeObj
        {
            public TextBlock attrLabel;
            public int id;
            public Diagram.Atrybut attr;
         
        }

        public struct MethodObj
        {            
            public TextBlock methodLabel;
            public int id;
            public Diagram.Operacja method;
        }

        private OBJ obj = OBJ.CLASS;
        public TextBlock l;
        Line fieldsline;
        Line methodsline;
        List<AttributeObj> attributesObj;
        List<MethodObj> methodsObj;
        Binding bind1;
        Binding bind2;        
        public OurListBox olb = new OurListBox();
        TextBlock newAttr,newMethod;
        Rectangle nr,mr;
        Rectangle lr;

        public override void showHints(bool a_show)
        {
            int thick = a_show ? 1 : 0;
            if (nr!=null)
                nr.StrokeThickness = thick;
            if (mr!=null)
                mr.StrokeThickness = thick;
            if (lr!=null)
                lr.StrokeThickness = thick;

        }


        public override Type getType() 
        {
            if (obj == OBJ.CLASS)
            {
                return typeof(KlasaObj);
            }
            else if (obj == OBJ.INTERFACE) 
            {
                return typeof(InterfejsObj);
            }
            return null;
        }
        
        private void deleteObject(object o)
        {
            if (o is AttributeObj)
            {
                Diagram.Klasa kUml = (Diagram.Klasa)guml.obj_uml;
                AttributeObj aObj = (AttributeObj)o;
                kUml.UsunAtrybut(aObj.attr);
                this.Refresh();
            }
            else if (o is MethodObj)
            {
                if (getType() == typeof(KlasaObj))
                {
                    Diagram.Klasa kUml = (Diagram.Klasa)guml.obj_uml;
                    MethodObj mObj = (MethodObj)o;
                    kUml.UsunOperacje(mObj.method);
                    this.Refresh();
                }
                else if (getType() == typeof(InterfejsObj))
                {
                    Diagram.Interfejs kUml = (Diagram.Interfejs)guml.obj_uml;
                    MethodObj mObj = (MethodObj)o;
                    kUml.UsunOperacje(mObj.method);
                    this.Refresh();
                }
            }
            else if (o is ItemAttribute) 
            {
                ItemAttribute item = (ItemAttribute)o;                
                item.myAttr.ShowInGui = !item.myAttr.ShowInGui;
                if (item.myAttr.ShowInGui)
                    item.panel.Opacity = 1.0f;
                else
                    item.panel.Opacity = 0.5f;
                ColorAnimation colorAnimation = new ColorAnimation(Color.FromRgb(200, 200, 200), Color.FromRgb(255, 255, 255), new TimeSpan(0, 0, 0, 0, 200));
                colorAnimation.AccelerationRatio = 0.5;                
                SolidColorBrush scb = new SolidColorBrush(Color.FromRgb(255, 255, 255));
                item.panel.Background = scb;
                foreach (UIElement elem in item.panel.Children)
                {
                    if (elem is Control)
                    {
                        ((Control)elem).Background = scb;
                    }
                }
                scb.BeginAnimation(SolidColorBrush.ColorProperty, colorAnimation);
            }
            else if (o is ItemMethod)
            {
                Console.WriteLine("o is ItemMethod!");
                ItemMethod item = (ItemMethod)o;
                item.method.ShowInGui = !item.method.ShowInGui;
                if (item.method.ShowInGui)
                    item.panel.Opacity = 1.0f;
                else
                    item.panel.Opacity = 0.5f;
                ColorAnimation colorAnimation = new ColorAnimation(Color.FromRgb(200, 200, 200), Color.FromRgb(255, 255, 255), new TimeSpan(0, 0, 0, 0, 200));
                colorAnimation.AccelerationRatio = 0.5;
                SolidColorBrush scb = new SolidColorBrush(Color.FromRgb(255, 255, 255));
                item.panel.Background = scb;
                foreach (UIElement elem in item.panel.Children)
                {
                    if (elem is Control)
                    {
                        ((Control)elem).Background = scb;
                    }
                }
                scb.BeginAnimation(SolidColorBrush.ColorProperty, colorAnimation);
            }
        }

        public object SwapItems(double sX,double sY,double kX,double kY)
        {
            object ret = null;
            double panelX = InkCanvas.GetLeft(guml.panel);
            double panelY = InkCanvas.GetTop(guml.panel);
            double wsX = sX - panelX;
            double wsY = sY - panelY;

            if (wsX < 0) return null;
            else if (wsY < 0) return null;
            else if (wsX > guml.panel.ActualWidth) return null;
            else if (wsY > guml.panel.ActualHeight) return null;



            return ret;
        }
        
        public object DeletePointOnObject(double sX,double sY)
        {
            double panelX = InkCanvas.GetLeft(guml.panel);
            double panelY = InkCanvas.GetTop(guml.panel);            
            double wsX = sX - panelX;
            double wsY = sY - panelY;

            if (wsX < 0) return null;
            else if (wsY < 0) return null;
            else if (wsX > guml.panel.ActualWidth) return null;
            else if (wsY > guml.panel.ActualHeight) return null;

            if (showBackContent)
            {
                Console.WriteLine("checking back content...");
                TreeViewItem aHeader = (TreeViewItem)(((TreeViewItem)olb.Items[0]).Items[0]);
                TreeViewItem mHeader = (TreeViewItem)(((TreeViewItem)olb.Items[0]).Items[1]);                
                
                foreach (ItemAttribute item in aHeader.Items)
                {
                    StackPanel sp = item.panel;
                    GeneralTransform gT = sp.TransformToAncestor(olb);
                    Point myOffset = gT.Transform(new Point(0, 0));
                    double aX = myOffset.X;
                    double aY = myOffset.Y;
                    double aWidth = sp.ActualWidth;
                    double aHeight = sp.ActualHeight;
                    if ((wsX > aX) && (wsX < aX + aWidth) && (wsY > aY) && (wsY < aY + aHeight))
                    {
                        deleteObject(item);
                        return item;
                    }
                }

                foreach (ItemMethod item in mHeader.Items)
                {
                    StackPanel sp = item.panel;
                    GeneralTransform gT = sp.TransformToAncestor(olb);
                    Point myOffset = gT.Transform(new Point(0, 0));
                    double aX = myOffset.X;
                    double aY = myOffset.Y;
                    double aWidth = sp.ActualWidth;
                    double aHeight = sp.ActualHeight;
                    if ((wsX > aX) && (wsX < aX + aWidth) && (wsY > aY) && (wsY < aY + aHeight))
                    {
                        deleteObject(item);
                        return item;
                    }
                }

            }
            else
            {
                Console.WriteLine("checking front content...");
                foreach (AttributeObj attr in attributesObj)
                {
                    double aX = Canvas.GetLeft(attr.attrLabel);
                    double aY = Canvas.GetTop(attr.attrLabel);
                    double aWidth = attr.attrLabel.ActualWidth;
                    double aHeight = attr.attrLabel.ActualHeight;
                    if ((wsX > aX) && (wsX < aX + aWidth) && (wsY > aY) && (wsY < aY + aHeight))
                    {
                        deleteObject(attr);
                        return attr;
                    }
                }
                foreach (MethodObj method in methodsObj)
                {
                    double aX = Canvas.GetLeft(method.methodLabel);
                    double aY = Canvas.GetTop(method.methodLabel);
                    double aWidth = method.methodLabel.ActualWidth;
                    double aHeight = method.methodLabel.ActualHeight;
                    if ((wsX > aX) && (wsX < aX + aWidth) && (wsY > aY) && (wsY < aY + aHeight))
                    {
                        deleteObject(method);
                        return method;
                    }
                }
            }
            return null;
        }

        public override void generateBackContent()
        {
            if (!showBackContent)
            {
                if (obj == OBJ.INTERFACE)
                {
                    olb.objInterface = (Diagram.Interfejs)this.guml.obj_uml;
                    olb.RefreshWithInterfaceObject(guml.canvas);
                }
                else if (obj == OBJ.CLASS)
                {
                    olb.objClass = (Diagram.Klasa)this.guml.obj_uml;
                    olb.RefreshWithClassObject(guml.canvas);
                }
                System.Console.WriteLine("generateBackContent()");
            }
            else
            {
                olb.Effect = null;
            }
            showBackContent = !showBackContent;
        }

        public override void swapToBackContent()
        {                
                if (showBackContent)
                {
                    DropShadowEffect myDropShadowEffect = new DropShadowEffect();
                    Color myShadowColor = new Color();
                    myShadowColor.ScA = 1;
                    myShadowColor.ScB = 0;
                    myShadowColor.ScG = 0;
                    myShadowColor.ScR = 0;
                    myDropShadowEffect.Color = myShadowColor;
                    myDropShadowEffect.Direction = 320;
                    myDropShadowEffect.ShadowDepth = 0;
                    myDropShadowEffect.BlurRadius = 7;
                    myDropShadowEffect.Opacity = 0.3;
                    olb.Effect = myDropShadowEffect;
                    olb.Visibility = Visibility.Visible;                        
                    showControls(false, olb);
                    System.Console.WriteLine("swapToBackContent()");                    
                }
                else
                {
                    Refresh();                    
                    olb.Visibility = Visibility.Hidden;
                    showControls(true, olb);
                    System.Console.WriteLine("swapToFrontContent()");
                    if (mr != null)
                    {
                        mr.Width = getWidth() - 10;
                    }
                    if (nr != null)
                    {
                        nr.Width = getWidth() - 10;
                    }
                }

                
        }

        public KlasaObj(OBJ tobj, String a_title, int a_width, int a_height, int a_left, int a_top, OurCanvas a_canvas, int a_id, GUML aguml)
            : base(aguml)
        {

            obj = tobj;

            if (a_width < 0) { a_left = a_left + a_width; a_width = -a_width; }
            if (a_height < 0) { a_top = a_top + a_height; a_height = -a_height; }

            x = a_left;
            y = a_top;
            width = a_width;
            height = a_height;

            LinearGradientBrush myLinearGradientBrush =
                            new LinearGradientBrush();
            myLinearGradientBrush.StartPoint = new Point(0, 0);
            myLinearGradientBrush.EndPoint = new Point(0, 1);

            if (obj == OBJ.CLASS)
            {
                myLinearGradientBrush.GradientStops.Add(new GradientStop(Color.FromRgb(254, 239, 186), 0.0));
                myLinearGradientBrush.GradientStops.Add(new GradientStop(Color.FromRgb(252, 223, 108), 1.0));
            }
            else if (obj == OBJ.INTERFACE)
            {
                myLinearGradientBrush.GradientStops.Add(new GradientStop(Color.FromRgb(232, 251, 188), 0.0));
                myLinearGradientBrush.GradientStops.Add(new GradientStop(Color.FromRgb(215, 251, 129), 1.0));
            }

            guml.panel = new Canvas();
            InkCanvas.SetLeft(guml.panel, x);
            InkCanvas.SetTop(guml.panel, y);
            guml.panel.Width = width;
            guml.panel.Height = height;
            guml.panel.Background = myLinearGradientBrush;
            guml.panel.Opacity = 0.9;            

            Rectangle r = new Rectangle();
            r.Width = width;
            r.Height = height;
            InkCanvas.SetLeft(r, 0);
            InkCanvas.SetTop(r, 0);
            r.Stroke = Brushes.Black;
            r.StrokeThickness = 1;
            guml.panel.Children.Add(r);

            attributesObj = new List<AttributeObj>();
            methodsObj = new List<MethodObj>();
            setZOrder(a_id);

            l = new TextBlock();
//            MessageBox.Show(l.FontFamily.BaseUri + " " + l.FontFamily.FamilyTypefaces.ToString() + " " + l.FontFamily.FamilyNames.ToString());
            fieldsline = new Line();
            fieldsline.X1 = 0;
            fieldsline.Y1 = 35;
            fieldsline.X2 = width;
            fieldsline.Y2 = 35;
            fieldsline.StrokeThickness = 1;
            fieldsline.Stroke = Brushes.Black;
            guml.panel.Children.Add(fieldsline);

            l.MouseDown += new MouseButtonEventHandler(l_MouseDown);

            if (obj == OBJ.CLASS)
            {
                l.Text = a_title;
            }
            else
            {
                fieldsline.Visibility = Visibility.Hidden;
                l.Inlines.Clear();
                l.Inlines.Add("<< interface >>\r\n");
                l.Inlines.Add(new Bold(new Run(a_title)));
            }
           // l.FontWeight = FontWeights.Bold;            
            l.TextAlignment = TextAlignment.Center;
            l.Width = width;
            l.Height = 50;
            InkCanvas.SetLeft(l, 0);
            InkCanvas.SetTop(l, 0);
            Canvas.SetTop(l, 7);
            guml.panel.Children.Add(l);

            lr = new Rectangle();
            lr.Width = width - 10;
            
            lr.Stroke = Brushes.Black;
            lr.StrokeThickness = 1;
            lr.Fill = new SolidColorBrush(Color.FromArgb(10, 255, 255, 255));
            lr.StrokeDashCap = PenLineCap.Square;
            lr.StrokeDashArray.Add(5);
            lr.Opacity = 0.5;
            lr.MouseDown += new MouseButtonEventHandler(l_MouseDown);
            Canvas.SetLeft(lr, 5);
            Canvas.SetTop(lr, 5);
            guml.panel.Children.Add(lr);            


          

            methodsline = new Line();
            methodsline.X1 = 0;
            methodsline.Y1 = 35;
            methodsline.X2 = width;
            methodsline.Y2 = 35;

            if (obj == OBJ.INTERFACE)
            {
                methodsline.Y1 = methodsline.Y2 = 50;
                lr.Height = 40;
                fieldsline.Visibility = Visibility.Hidden;
            }
            else
            {
                l.FontWeight = FontWeights.Bold;
                lr.Height = 25;
            }

            methodsline.StrokeThickness = 1;
            methodsline.Stroke = Brushes.Black;
            guml.panel.Children.Add(methodsline);
            guml.canvas = a_canvas;
            guml.canvas.IsHitTestVisible = true;

            bind1 = new Binding("WidthProperty");
            bind1.Source = guml.panel;
            bind1.Path = new PropertyPath(Canvas.WidthProperty);
            bind2 = new Binding("HeightProperty");
            bind2.Source = guml.panel;
            bind2.Path = new PropertyPath(Canvas.HeightProperty);
            r.SetBinding(Rectangle.WidthProperty, bind1);
            r.SetBinding(Rectangle.HeightProperty, bind2);
//            l.SetBinding(Label.WidthProperty, bind1);
            methodsline.SetBinding(Line.X2Property, bind1);
            fieldsline.SetBinding(Line.X2Property, bind1);
            olb.SetBinding(TreeView.WidthProperty, bind1);
            olb.SetBinding(TreeView.HeightProperty, bind2);
            olb.Visibility = Visibility.Hidden;
            guml.panel.Children.Add(olb);
            guml.panel.UpdateLayout();
            updateDependencyProperties();
            guml.panel.SnapsToDevicePixels = true;
            methodsline.SnapsToDevicePixels = true;
            fieldsline.SnapsToDevicePixels = true;
            guml.canvas.Children.Add(guml.panel);
        }        

        void l_MouseDown(object sender, MouseButtonEventArgs e)
        {
            if (SignalR.windowParent.handWrite != null) return;
            SignalR.windowParent.handWrite = new UCUTextRecognizer.HandWrite();
            UCUTextRecognizer.HandWrite handWrite = SignalR.windowParent.handWrite;            
            handWrite.InitializeComponent();

            try
            {
                if (getType() == typeof(KlasaObj))
                {
                    if (!guml.obj_uml.Nazwa.StartsWith("Klasa"))
                    {
                        handWrite.setExistingText(guml.obj_uml.Nazwa);
                    }
                }
                else if (getType() == typeof(InterfejsObj))
                {
                    if (!guml.obj_uml.Nazwa.StartsWith("Interfejs"))
                    {
                        handWrite.setExistingText(guml.obj_uml.Nazwa);
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }


            double sx = SignalR.windowParent.sv.HorizontalOffset + 50;            
            double nw = SignalR.windowParent.sv.ActualWidth - 100;
            double sy = getY() + 30;
            double nh = 180;
            handWrite.Width = nw;
            handWrite.Height = nh;

            InkCanvas.SetLeft(handWrite, sx);
            InkCanvas.SetTop(handWrite, sy);
            handWrite.Opacity = 1.0f;
            //
            handWrite.bindWithObject(guml.obj_uml, guml.canvas, guml.umlobj);
            SignalR.windowParent.active_canvas.Children.Add(handWrite);
            e.Handled = true;
        }

        public override void updateDependencyProperties()
        {
            base.updateDependencyProperties();           
            lr.Width = getWidth() - 10;
            l.Width = getWidth() - 10;
            if (mr!=null)
                mr.Width = getWidth() - 10;
            if (nr!=null)
                nr.Width = getWidth() - 10;
            if (newMethod!=null)
            newMethod.Width = getWidth() - 10;
            if (newAttr!=null)
            newAttr.Width = getWidth()-10;

        }

        public override void Refresh()
        {
            if (width == 0) return;            
            if (getType() == typeof(InterfejsObj))
            {
                
                l.Inlines.Clear();
                l.Inlines.Add("<< interface >>\r\n");
                l.Inlines.Add(new Bold(new Run(guml.obj_uml.Nazwa)));
                foreach (MethodObj method in methodsObj)
                {
                    guml.panel.Children.Remove(method.methodLabel);
                }                
                guml.panel.Children.Remove(newMethod);                
                guml.panel.Children.Remove(mr);                
                methodsObj.Clear();

                Visibility vis = Visibility.Visible;
                if (olb.Visibility == Visibility.Visible)
                    vis = Visibility.Hidden;

                Diagram.Interfejs obj = guml.obj_uml as Diagram.Interfejs;
                int offy = 0;
                int sy = 50;
                
                if (obj.IloscOperacji > 0) offy = 5;
                for (int i = 0; i < obj.IloscOperacji; i++)
                {
                    Diagram.Operacja op = obj.GetOperacje(i);

                     if (!op.ShowInGui)
                        continue;

                    MethodObj mObj = new MethodObj();
                    mObj.method = op;
                    mObj.id = i;
                    String attrstr = "";
                    
                    /* TODO - visibility */
                    String content_string = op.Visibility+" " + op.Typ.Nazwa + " " + op.Nazwa + "(" + attrstr + ")";
                    mObj.methodLabel = new TextBlock();
                    mObj.methodLabel.MouseDown += new MouseButtonEventHandler(methodLabel_MouseDown);
                    mObj.methodLabel.Width = width;
                    mObj.methodLabel.SetBinding(Label.WidthProperty, bind1);
                    mObj.methodLabel.Tag = mObj.method;
                    //--
                    mObj.methodLabel.Inlines.Add(" ");
                    mObj.methodLabel.Inlines.Add(new Italic(new Run(mObj.method.Visibility)));
                    mObj.methodLabel.Inlines.Add(" ");
                    mObj.methodLabel.Inlines.Add(new Bold(new Run(op.Typ.Nazwa)));
                    mObj.methodLabel.Inlines.Add(" " + op.Nazwa);
                    mObj.methodLabel.Inlines.Add("(");
                    for (int j = 0; j < op.IloscAtrybutow; j++)
                    {
                        Diagram.Atrybut par = op.GetAtrybut(j);
                        mObj.methodLabel.Inlines.Add(par.Nazwa);
                        mObj.methodLabel.Inlines.Add(": ");
                        mObj.methodLabel.Inlines.Add(new Bold(new Run(par.Typ.Nazwa)));
                        //attrstr = attrstr + par.Nazwa + ": " + par.Typ.Nazwa;
                        if (j < op.IloscAtrybutow - 1)  mObj.methodLabel.Inlines.Add(", ");
                    }

//                    mObj.methodLabel.Inlines.Add(attrstr);
                    mObj.methodLabel.Inlines.Add(")");                    
                    Canvas.SetLeft(mObj.methodLabel, 2);
                    Canvas.SetTop(mObj.methodLabel,  sy+offy);
                    mObj.methodLabel.Visibility = vis;
                    guml.panel.Children.Add(mObj.methodLabel);
                    methodsObj.Add(mObj);
                    offy += 15;
                }
                // zostaw puste pole na nowy atrybut
                newMethod = new TextBlock();
                newMethod.Text = "dodaj metodę...";
                newMethod.FontStyle = FontStyles.Italic;
                mr = new Rectangle();
                mr.Width = width - 10;
                mr.Height = 17;
                mr.Stroke = Brushes.Black;
                mr.StrokeThickness = 1;
                if (SignalR.windowParent.Hint.Opacity == 0.5f)
                    mr.StrokeThickness = 0;
                mr.Fill = new SolidColorBrush(Color.FromArgb(10, 255, 255, 255));
                mr.StrokeDashCap = PenLineCap.Square;
                mr.StrokeDashArray.Add(5);
                mr.Opacity = 0.5;
                mr.MouseDown += new MouseButtonEventHandler(mr_MouseDown);
                newMethod.MouseDown += mr_MouseDown;
                Canvas.SetLeft(mr, 5);
                Canvas.SetTop(mr, sy + offy + 5);
                Canvas.SetLeft(newMethod, 7);
                Canvas.SetTop(newMethod, sy + offy + 5);
                guml.panel.Children.Add(mr);
                guml.panel.Children.Add(newMethod);
                mr.Visibility = vis;
                newMethod.Visibility = vis;
                fieldsline.Visibility = Visibility.Hidden;
                fieldsline.X1 = fieldsline.X2 = fieldsline.Y1 = fieldsline.Y2 = 0;
            }
            else if (getType() == typeof(KlasaObj))
            {
                l.Text = guml.obj_uml.Nazwa;
                Visibility vis = Visibility.Visible;
                if (olb.Visibility == Visibility.Visible)
                    vis = Visibility.Hidden;

                double max_height_fields = 0.4 * height;
                double max_height_methods = 0.4 * height;

                double sy = 35;

                fieldsline.Y1 = fieldsline.Y2 = 35;
                Diagram.Klasa obj = guml.obj_uml as Diagram.Klasa;

                if (obj == null) return;

                foreach (AttributeObj attr in attributesObj)
                {
                    guml.panel.Children.Remove(attr.attrLabel);
                }
                foreach (MethodObj method in methodsObj)
                {
                    guml.panel.Children.Remove(method.methodLabel);
                }
                guml.panel.Children.Remove(newAttr);
                guml.panel.Children.Remove(newMethod);
                guml.panel.Children.Remove(nr);
                guml.panel.Children.Remove(mr);
                attributesObj.Clear();
                methodsObj.Clear();
                double offy = 0;

                if (obj.IloscAtrybutow > 0) offy = 5;

                for (int i = 0; i < obj.IloscAtrybutow; i++)
                {
                    Diagram.Atrybut attr = obj.GetAtrybut(i);

                    // pomijaj niewidoczne

                    if (!attr.ShowInGui)
                    {
                        System.Console.WriteLine("showInGui == false");
                        continue;
                    }

                    AttributeObj attrObj = new AttributeObj();
                    attrObj.attrLabel = new TextBlock();
                    attrObj.attrLabel.MouseDown += new MouseButtonEventHandler(attrLabel_MouseDown);
                    attrObj.id = i;
                    attrObj.attr = attr;
                    attrObj.attrLabel.Width = width;
                    attrObj.attrLabel.SetBinding(Label.WidthProperty, bind1);
                    attrObj.attrLabel.Tag = attr;                    
                    Run vis_r = new Run();
                    vis_r.FontWeight = FontWeights.Bold;
                    vis_r.Text = " " + attr.Visibility + " ";
                    Run type_r = new Run();
                    type_r.FontStyle = FontStyles.Oblique;
                    type_r.Text = attr.Typ.Nazwa;
                    attrObj.attrLabel.Inlines.Add(vis_r);
                    attrObj.attrLabel.Inlines.Add(" ");                                        
                    attrObj.attrLabel.Inlines.Add(attr.Nazwa);
                    attrObj.attrLabel.Inlines.Add(": ");
                    attrObj.attrLabel.Inlines.Add(new Bold(new Run(attr.Typ.Nazwa)));
                    Canvas.SetLeft(attrObj.attrLabel, 0);
                    Canvas.SetTop(attrObj.attrLabel, sy + offy);
                    attrObj.attrLabel.Visibility = vis;
                    guml.panel.Children.Add(attrObj.attrLabel);
                    attributesObj.Add(attrObj);
                    offy += 15;
                }

                // zostaw puste pole na nowy atrybut
                newAttr = new TextBlock();
                newAttr.Text = "dodaj atrybut...";
                newAttr.FontStyle = FontStyles.Italic;
                nr = new Rectangle();
                nr.Width = width - 10;
                nr.Height = 17;
                nr.Fill = new SolidColorBrush(Color.FromArgb(10, 255, 255, 255));
                nr.Stroke = Brushes.Black;
                nr.StrokeThickness = 1;
                if (SignalR.windowParent.Hint.Opacity == 0.5f)
                    nr.StrokeThickness = 0;
                nr.StrokeDashCap = PenLineCap.Square;
                nr.StrokeDashArray.Add(5);
                newAttr.MouseDown += nr_MouseDown;
                nr.MouseDown += new MouseButtonEventHandler(nr_MouseDown);
                Canvas.SetLeft(nr, 5);
                Canvas.SetTop(nr, sy + offy + 5);
                Canvas.SetLeft(newAttr, 7);
                Canvas.SetTop(newAttr, sy + offy + 5);
                guml.panel.Children.Add(nr);
                guml.panel.Children.Add(newAttr);
                offy += 15;


                sy = sy + 10;
                methodsline.Y1 = methodsline.Y2 = sy + offy;

                if (obj.IloscOperacji > 0)
                    offy = offy + 5;


                for (int i = 0; i < obj.IloscOperacji; i++)
                {
                    Diagram.Operacja op = obj.GetOperacje(i);

                    if (!op.ShowInGui)
                        continue;
                    
                    MethodObj mObj = new MethodObj();
                    mObj.method = op;
                    mObj.id = i;
                    String attrstr = "";
             
                    /* TODO - visibility */
                    String content_string = op.Visibility+" " + op.Typ.Nazwa + " " + op.Nazwa + "(" + attrstr + ")";
                    mObj.methodLabel = new TextBlock();
                    mObj.methodLabel.MouseDown +=new MouseButtonEventHandler(methodLabel_MouseDown);
                    mObj.methodLabel.Width = width;
                    mObj.methodLabel.Tag = mObj.method;
                    mObj.methodLabel.SetBinding(Label.WidthProperty, bind1);
                    mObj.methodLabel.Inlines.Add(" ");
                    mObj.methodLabel.Inlines.Add(new Italic(new Run(mObj.method.Visibility)));
                    mObj.methodLabel.Inlines.Add(" ");
                    mObj.methodLabel.Inlines.Add(new Bold(new Run(op.Typ.Nazwa)));
                    mObj.methodLabel.Inlines.Add(" " + op.Nazwa);
                    mObj.methodLabel.Inlines.Add("(");

                    for (int j = 0; j < op.IloscAtrybutow; j++)
                    {
                        Diagram.Atrybut par = op.GetAtrybut(j);
                        mObj.methodLabel.Inlines.Add(par.Nazwa);
                        mObj.methodLabel.Inlines.Add(": ");
                        mObj.methodLabel.Inlines.Add(new Bold(new Run(par.Typ.Nazwa)));
                        //attrstr = attrstr + par.Nazwa + ": " + par.Typ.Nazwa;
                        if (j < op.IloscAtrybutow - 1) mObj.methodLabel.Inlines.Add(", ");
                    }

                    mObj.methodLabel.Inlines.Add(")");                    
                    Canvas.SetLeft(mObj.methodLabel, 2);
                    Canvas.SetTop(mObj.methodLabel, sy + offy);
                    mObj.methodLabel.Visibility = vis;
                    guml.panel.Children.Add(mObj.methodLabel);
                    methodsObj.Add(mObj);
                    offy += 15;
                }
                // zostaw puste pole na nowy atrybut
                newMethod = new TextBlock();
                newMethod.Text = "dodaj metodę...";
                newMethod.FontStyle = FontStyles.Italic;
                mr = new Rectangle();
                mr.Width = width - 10;
                mr.Height = 17;
                mr.Stroke = Brushes.Black;
                mr.StrokeThickness = 1;
                if (SignalR.windowParent.Hint.Opacity == 0.5f)
                    mr.StrokeThickness = 0;
                mr.Fill = new SolidColorBrush(Color.FromArgb(10, 255, 255, 255));
                mr.StrokeDashCap = PenLineCap.Square;
                mr.StrokeDashArray.Add(5);
                mr.MouseDown += mr_MouseDown;
                newMethod.MouseDown += mr_MouseDown;
                Canvas.SetLeft(mr, 5);
                Canvas.SetTop(mr, sy + offy + 5);
                Canvas.SetLeft(newMethod, 7);
                Canvas.SetTop(newMethod, sy + offy + 5);
                guml.panel.Children.Add(mr);
                guml.panel.Children.Add(newMethod);
                nr.Opacity = 0.5;
                mr.Opacity = 0.5;
                mr.Visibility = nr.Visibility = newAttr.Visibility = newMethod.Visibility = vis;
            }
        }

        void methodLabel_MouseDown(object sender, MouseButtonEventArgs e)
        {
            Diagram.Operacja oper = ((TextBlock)sender).Tag as Diagram.Operacja;
            String txt = "";
            txt = oper.Visibility + " " + oper.Nazwa+"(";

            for (int i = 0; i < oper.IloscAtrybutow; i++)
            {
                Diagram.Atrybut attr = oper.GetAtrybut(i);
                txt = txt + attr.Nazwa + ":" + attr.Typ.Nazwa;
                if (i < oper.IloscAtrybutow - 1)
                    txt = txt + ",";
            }

            txt = txt + "):"+oper.Typ.Nazwa;

            if (SignalR.windowParent.handWrite != null) return;
            SignalR.windowParent.handWrite = new UCUTextRecognizer.HandWrite();
            UCUTextRecognizer.HandWrite handWrite = SignalR.windowParent.handWrite;            
            handWrite.InitializeComponent();
            handWrite.setExistingText(txt);
            
            double sy = getY() + Canvas.GetTop(mr) - 20;            
            double nh = 180;

            double sx = SignalR.windowParent.sv.HorizontalOffset + 50;
            double nw = SignalR.windowParent.sv.ActualWidth - 100;            

            handWrite.Width = nw;
            handWrite.Height = nh;

            InkCanvas.SetLeft(handWrite, sx);
            InkCanvas.SetTop(handWrite, sy);
            handWrite.Opacity = 1.0f;
            //
            Diagram.ModelDiagramu.dodawaj = false;            
            Diagram.ModelDiagramu.dodawaj = true;
            handWrite.bindWithObject(oper, guml.canvas, guml.umlobj);            
            SignalR.windowParent.active_canvas.Children.Add(handWrite);
            e.Handled = true;            
        }

        void mr_MouseDown(object sender, MouseButtonEventArgs e)
        {
            if (SignalR.windowParent.handWrite != null) return;
            SignalR.windowParent.handWrite = new UCUTextRecognizer.HandWrite();
            UCUTextRecognizer.HandWrite handWrite = SignalR.windowParent.handWrite;
            handWrite.InitializeComponent();
            handWrite.setHint();
            
            double sy = getY() + Canvas.GetTop(mr) - 20;            
            double nh = 180;
            double sx = SignalR.windowParent.sv.HorizontalOffset + 50;
            double nw = SignalR.windowParent.sv.ActualWidth - 100;            
            handWrite.Width = nw;
            handWrite.Height = nh;

            InkCanvas.SetLeft(handWrite, sx);
            InkCanvas.SetTop(handWrite, sy);
            handWrite.Opacity = 1.0f;
            //
            Diagram.ModelDiagramu.dodawaj = false;
            Diagram.Operacja dOper = new Diagram.Operacja("CHANGE","int");
            Diagram.ModelDiagramu.dodawaj = true;
            handWrite.bindWithObject(dOper, guml.canvas, guml.umlobj);
            SignalR.windowParent.active_canvas.Children.Add(handWrite);
            e.Handled = true;            
        }

        void nr_MouseDown(object sender, MouseButtonEventArgs e)
        {
            if (SignalR.windowParent.handWrite != null) return;
            SignalR.windowParent.handWrite = new UCUTextRecognizer.HandWrite();
            UCUTextRecognizer.HandWrite handWrite = SignalR.windowParent.handWrite;            
            handWrite.InitializeComponent();
            
            double sy = getY() + Canvas.GetTop(mr) - 20;            
            double nh = 180;
            double sx = SignalR.windowParent.sv.HorizontalOffset + 50;
            double nw = SignalR.windowParent.sv.ActualWidth - 100;            
            handWrite.Width = nw;
            handWrite.Height = nh;
            InkCanvas.SetLeft(handWrite, sx);
            InkCanvas.SetTop(handWrite, sy);
            handWrite.Opacity = 1.0f;
            //
            Diagram.ModelDiagramu.dodawaj = false;
            Diagram.Atrybut dAttr = new Diagram.Atrybut("CHANGE", "int");
            Diagram.ModelDiagramu.dodawaj = true;
            handWrite.bindWithObject(dAttr, guml.canvas, guml.umlobj);
            SignalR.windowParent.active_canvas.Children.Add(handWrite);
            e.Handled = true;
        }

        void attrLabel_MouseDown(object sender, MouseButtonEventArgs e)
        {
            if (SignalR.windowParent.handWrite != null) return;
            Diagram.Atrybut dAttr = ((TextBlock)sender).Tag as Diagram.Atrybut;
            String txt = dAttr.Visibility + " " + dAttr.Nazwa + ":" + dAttr.Typ.Nazwa;

            SignalR.windowParent.handWrite = new UCUTextRecognizer.HandWrite();
            UCUTextRecognizer.HandWrite handWrite = SignalR.windowParent.handWrite;            
            handWrite.InitializeComponent();            
            handWrite.setExistingText(txt);

            double sy = getY() + Canvas.GetTop(mr) - 20;            
            double nh = 180;
            double sx = SignalR.windowParent.sv.HorizontalOffset + 50;
            double nw = SignalR.windowParent.sv.ActualWidth - 100;            
            handWrite.Width = nw;
            handWrite.Height = nh;

            InkCanvas.SetLeft(handWrite, sx);
            InkCanvas.SetTop(handWrite, sy);
            handWrite.Opacity = 1.0f;
            //            
            handWrite.bindWithObject(dAttr, guml.canvas, guml.umlobj);
            //(Diagram.Element)dAttr
            SignalR.windowParent.active_canvas.Children.Add(handWrite);
            e.Handled = true;            
        }


        public override void setX(int ax)
        {
            x = ax;
            InkCanvas.SetLeft(guml.panel, x);
        }

        public override void setY(int ay)
        {
            y = ay;
            InkCanvas.SetTop(guml.panel, y);
        }

        public override void setWidth(int a_width)
        {            
            width = a_width;
            l.Width = a_width;
        }
        public override void setHeight(int a_height)
        {
            height = a_height;
            l.Height = 50;
        }

    }
}
